package org.onvivals.app.websocket;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Slf4j
@Component
public class FunASRIntegration {

	private static final Map<String, FunASRClient> transcriberMap = new ConcurrentHashMap<>();
	private static final Map<String, Object> configTemplate = createConfigTemplate();

	private static Map<String, Object> createConfigTemplate() {
		Map<String, Object> config = new ConcurrentHashMap<>();
		config.put("chunk_size", new int[]{5, 10, 5});
		config.put("wav_format", "pcm");
		config.put("chunk_interval", 10);
		config.put("itn", true);
		config.put("mode", "2pass");
		config.put("hotwords", "");
		return config;
	}

	public boolean start(String channel) {
		try {
			FunASRClient client = new FunASRClient(new URI("ws://192.168.0.2:10095"));
//			FunASRClient client = new FunASRClient(new URI("ws://101.126.138.204:10095"));
			boolean connected = client.connectBlocking();
			log.info("FunASR 连接状态: {}", connected);
			Map<String, Object> config = new ConcurrentHashMap<>(configTemplate);
			config.put("wav_name", channel);
			client.sendConfig(config);
			transcriberMap.put(channel, client);
			return connected;
		} catch (Exception e) {
			log.error("连接失败", e);
		}
		return false;
	}

	public void process(String channel, byte[] byteArray) {
		FunASRClient client = transcriberMap.get(channel);
		if (client != null) {
			client.sendAudioData(byteArray);
		}
	}

	public String text(String channel) {
		FunASRClient client = transcriberMap.get(channel);
		if (client!=null) {
			Map<String, Object> ma = new ConcurrentHashMap<>();
			ma.put("is_speaking", false);
			client.sendConfig(ma);
			long timeout = 2; // 超时时间，单位：秒
			// 创建异步任务
			CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
				String resultText;
				do {
					resultText = client.text(channel);
				} while (StrUtil.isEmpty(resultText)); // 直到获得非空结果
				return resultText;
			});

			try {
				// 等待获取结果，超时时间为timeout秒
				return future.get(timeout, TimeUnit.SECONDS);
			} catch (TimeoutException e) {
				System.out.println("Timeout reached without receiving text.");
				return null; // 超时返回 null
			} catch (Exception e) {
				Thread.currentThread().interrupt();
				return null;
			}
		}else {
			return null;
		}
	}

	public void close(String channel) {
		FunASRClient client = transcriberMap.remove(channel);
		if (client != null) {
			client.close();
		}
	}

	public void clean(String channel) {
		FunASRClient client = transcriberMap.get(channel);
		if (client != null) {
			client.clean(channel);
		}
	}
}
